package controllers

import (
	"aiserver/pkg/config"
	"aiserver/pkg/services"
	"aiserver/pkg/store"
	"fmt"
	"strings"

	"gitee.com/wujianqiang/golibs/pkg/jwt"
	"gitee.com/wujianqiang/golibs/pkg/logging"
	"github.com/gofiber/fiber/v2"
)

type UserController struct {
	srv services.Service
}

// NewUserController creates a user handler.
func NewUserController(store store.Factory) *UserController {
	return &UserController{
		srv: services.NewService(store),
	}
}

func (c *UserController) GetUser(ctx *fiber.Ctx) error {
	ctx.Status(fiber.StatusOK).JSON(fiber.Map{
		"code": 0,
		"msg":  "ok",
		"data": "test",
	})
	return nil
}

func (c *UserController) SSo(ctx *fiber.Ctx) error {
	code := ctx.Query("code", "")
	fmt.Println(code)
	username, er := config.Appconfig.Keycloak.AuthCheckCode(code)
	if er != nil {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": er.Error(),
		})
		return nil
	}
	user, er := c.srv.Users().GetAndCreateUserByName(username)
	if er != nil {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": er.Error(),
		})
		return nil
	}
	res, er := config.Appconfig.Jwt.Gernate(jwt.UserData{
		ID:       int64(user.ID),
		Username: user.UserName,
	})
	if er != nil {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": er.Error(),
		})
	} else {
		fmt.Println(res)
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":     0,
			"token":    res.Token,
			"frelesh":  res.RefleshToken,
			"username": user.UserName,
			"userid":   user.ID,
		})
	}

	return nil
}

func (uc *UserController) NewAuth() fiber.Handler {
	return func(c *fiber.Ctx) error {
		auth := c.Get(fiber.HeaderAuthorization)
		token_total := strings.Fields(auth)
		if len(token_total) != 2 {
			return c.Status(401).JSON(fiber.Map{
				"code":    2,
				"status":  "error",
				"message": "Unauthorized",
			})
		}
		token := token_total[1]
		jwtuser, freshToken, err := config.Appconfig.Jwt.Parse(token)
		if err != nil {
			return c.Status(401).JSON(fiber.Map{
				"code":    2,
				"status":  "error",
				"message": "Unauthorized",
			})
		}
		if freshToken {
			return c.Status(401).JSON(fiber.Map{
				"code":    2,
				"status":  "error",
				"message": "the token is refresh",
			})

		}

		user, er := uc.srv.Users().GetUserByName(jwtuser.Username)
		if er != nil {
			return c.Status(400).JSON(fiber.Map{
				"code":    2,
				"status":  "error",
				"message": "can't  get the user in db",
			})
		}
		c.Locals("user", user)
		return c.Next()
	}

}

type RefleshToken struct {
	Token string `json:"token"`
}

func (c *UserController) RefleshToken(ctx *fiber.Ctx) error {

	var reflesh RefleshToken
	er := ctx.BodyParser(&reflesh)
	logging.Logger.Info("reflesh token: ", reflesh.Token)
	if er != nil {
		return ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": er.Error(),
		})
	}
	jwtuser, freshToken, err := config.Appconfig.Jwt.Parse(reflesh.Token)
	if err != nil {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": err.Error(),
		})
		return nil
	}
	if !freshToken {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": "token is not  fresh token",
		})
		return nil
	}
	res, er := config.Appconfig.Jwt.Gernate(jwt.UserData{
		ID:       int64(jwtuser.ID),
		Username: jwtuser.Username,
	})
	if er != nil {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":  1,
			"ermsg": er.Error(),
		})
	} else {
		ctx.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":     0,
			"token":    res.Token,
			"frelesh":  res.RefleshToken,
			"username": jwtuser.Username,
			"userid":   jwtuser.ID,
		})
	}

	return nil
}
